#coding: utf-8

import logging
from consts import *
import itertools

class RelationshipsExtractor:

    def __init__(self, ldb, entities, prepositions):
        self.ldb = ldb
        self.entities = entities
        self.prepositions = prepositions

    def load_noun_noun_relationship(self, first_sort, second_sort, preposition):
        result = []
        logging.debug('fetching relationships for sort1: ' + first_sort + ' sort2: ' + second_sort + ' preposition: ' + preposition)

        query_result = self.ldb.query_ldb(TABLE_NAMES.DPF, {DPF_FIELDS_NAMES.FIRST_SORT: first_sort,
                                                            DPF_FIELDS_NAMES.SECOND_SORT: second_sort,
                                                            DPF_FIELDS_NAMES.PREPOSITION: preposition})
        for s in query_result:
            logging.debug('-------relationship fetched!!!--------')
            logging.debug(s[5])
            result.append(PrepositionalFrame(s[1],s[2],s[3],s[4],s[5],s[6]))

        return result

    def load_verb_noun_relationship(self, semantic_entity, preposition, sort):
        result = []
        logging.debug('fetching relationships for semantic entity: ' + semantic_entity + ' sort: ' + sort + ' preposition: ' + preposition)

        query_result = self.ldb.query_ldb(TABLE_NAMES.DVPF, {DVPF_FIELDS_NAMES.SEMANTIC_ENTITY: semantic_entity,
                                                            DVPF_FIELDS_NAMES.SORT: sort,
                                                            DVPF_FIELDS_NAMES.PREPOSITION: preposition})
        for s in query_result:
            logging.debug('-------relationship fetched!!!--------')
            logging.debug(s[8])
            result.append(VerbalPrepositionalFrame(s[1],s[2],s[3],s[4],s[5],s[6],s[7],s[8],s[9]))

        return result

    def extract_relationships(self, tree, tagged_tokens_with_semantic_entities, default_entity=None, bottomup = True):

        """
            Extracts relationships from given sentence
        """

        try:
            #t.node contains node label ( S, NP , VP, etc...)
            tree.node
        except AttributeError:
            #that exception means 't' is tuple representing a leaf
            pass
        else:
            #bottom-up approach
            if bottomup:
                for child in tree:
                    self.extract_relationships(child, tagged_tokens_with_semantic_entities, default_entity, bottomup)

            # Now we know that t.node is defined
            if tree.node == 'NPP':

                #code below attaches adjectives to noun
                primary_nentity = None

                for child in tree:
                    try:
                        child.node
                    except AttributeError:
                        pass
                    else:
                        if child.node == 'NP' and not primary_nentity:
                            primary_nentity = self.entities[child]
                        elif child.node == 'PP' or primary_nentity:
                            #now take all possible pairs of sorts

                            relationships = []
                            second_nentity = self.entities[child]
                            preposition = self.prepositions[child]
                            for pair in itertools.product(primary_nentity.sorts, second_nentity.sorts):
                                relationship = self.load_noun_noun_relationship(pair[0], pair[1], preposition)
                                if relationship:
                                    relationships.extend(relationship)
                            relationshipindex = 1
                            if len(relationships) > 1:
                                relationshipindex = ask_clarification(CLARIFICATION_QUESTIONS.NOUN_NOUN_RELATIONSHIP,
                                    primary_nentity.concept + ' ' + preposition + ' ' +second_nentity.concept,
                                    map(lambda x: x.relation + ' ' + x.ex, relationships))
                            #print "%s(%s,%s)" % (
                            #first_nentity.concept, relationships[relationshipindex - 1].relation, second_nentity.concept)
                            self.entities[tree] = primary_nentity.add_modifier([relationships[relationshipindex - 1].relation, second_nentity.get_semantic_representation()])

            if tree.node == 'VPP':

                for child in tree:
                    try:
                        child.node
                    except AttributeError:
                        pass
                    else:
                        action_entity = None
                        if child.node == 'VP':
                            action_entity = self.entities[child]
                        elif child.node in ['PP', 'NP']:
                            relationships = []
                            nentity = self.entities[child]
                            preposition = self.prepositions[child]
                            #print nentity.concept, preposition
                            for sort in nentity.sorts:
                                relationship_list = self.load_verb_noun_relationship( action_entity.concept.split('*')[0], preposition, sort)
                                if relationship_list:
                                    relationships.extend(relationship_list)

                            relationshipindex = 1
                            if len(relationships) > 1:
                                relationshipindex = (CLARIFICATION_QUESTIONS.VERB_NOUN_RELATIONSHIP,
                                                     action_entity.concept + ' ' + preposition + ' ' + nentity.concept,
                                                     map(lambda x: x.trole + ' ' + x.expl, relationships))

                            self.entities[tree] = action_entity.add_modifier([relationships[relationshipindex - 1].trole, nentity.get_semantic_representation()])

            if tree.node == 'CLAUSE':
                preposition = 'N'
                relationships = []
                nentity = self.entities[tree[0]]
                action_entity = self.entities[tree[1]]
                if tree[0] in self.prepositions:
                    preposition = self.prepositions[tree[0]]

                for sort in nentity.sorts:
                    relationship = self.load_verb_noun_relationship( action_entity.concept.split('*')[0], preposition, sort)
                    if relationship:
                        relationships.extend(relationship)

                self.entities[tree] = action_entity.add_modifier([relationships[0].trole, nentity.get_semantic_representation()])
                #print action_entity.concept + '(' + relationships[0].trole + ', ' + nentity.concept + ')'

            if default_entity and tree.node == 'PP':
                #code below attaches adjectives to noun
                primary_nentity = default_entity
                relationships = []
                second_nentity = self.entities[tree]
                preposition = self.prepositions[tree]
                for pair in itertools.product(primary_nentity.sorts, second_nentity.sorts):
                    relationship = self.load_noun_noun_relationship(pair[0], pair[1], preposition)
                    if relationship:
                        relationships.extend(relationship)
                relationshipindex = 1
                if len(relationships) > 1:
                    relationshipindex = ask_clarification(CLARIFICATION_QUESTIONS.NOUN_NOUN_RELATIONSHIP,
                        primary_nentity.concept + ' ' + preposition + ' ' +second_nentity.concept,
                        map(lambda x: x.relation + ' ' + x.ex, relationships))
                    #print "%s(%s,%s)" % (
                #first_nentity.concept, relationships[relationshipindex - 1].relation, second_nentity.concept)
                self.entities[tree] = primary_nentity.add_modifier([relationships[relationshipindex - 1].relation, second_nentity.get_semantic_representation()])


            #up-bottom approach
            if not bottomup:
                for child in tree:
                    self.extract_relationships(child, tagged_tokens_with_semantic_entities, default_entity, bottomup)

class VerbalPrepositionalFrame:
    def __init__(self, semsit, fm, refl, vc, sprep, grc, str, trole, expl):
        self.semsit = semsit
        self.fm = fm
        self.refl = refl
        self.vc = vc
        self.sprep = sprep
        self.grc = grc
        self.str = str
        self.trole = trole
        self.expl = expl

class PrepositionalFrame:
    def __init__(self, prep,sr1,sr2,grc,relation,ex):
        self.prep = prep
        self.sr1 = sr1
        self.sr2 = sr2
        self.grc = grc
        self.relation = relation
        self.ex = ex
